/*
 * ml20gui - The MSN Webcam Recorder
 * This source code is under the GNU Public License (GPL).
 * Written by Ramiro Polla
 * Initial release: june 3rd, 2005
 *
 * this program records MSN Webcam Video
 */

#include "ml20gui.h"

static void fix_avi_info( hexport_t *hexport );
extern hexport_t *hexports;

DWORD WINAPI ExportThread( LPARAM lparam );

#define AVI_TIME 100

LRESULT CALLBACK AviProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
    hexport_t *thexport;

    for( thexport = hexports ; thexport ; thexport = thexport->next )
        if( thexport->hwnd == hwnd )
            break;

    switch(msg) {
    case WM_INITDIALOG:
    {
        char buf[MAX_PATH];
        char fullname[MAX_PATH];
        char mydocs[MAX_PATH];
        int i = 0;
        struct _stat sta;

        thexport = (hexport_t *) lParam;
        thexport->hwnd = hwnd;

        EnableWindow( GetDlgItem( hwnd, IDC_STOP_AVI ), FALSE );
        sprintf( buf, "%s {%d - %d}", thexport->vstream->fullname, thexport->decoder->in->fnum, thexport->decoder->out->fnum );
        SetDlgItemText( hwnd, IDC_INPUT_EDIT, buf );

        strcpy( buf, thexport->vstream->fullname );
        PathStripPath( buf );
        PathRemoveExtension( buf );

        SHGetSpecialFolderPath( NULL, mydocs, CSIDL_PERSONAL, 1 );

        do {
            char istring[8];

            sprintf( istring, " (%d)", i );

            sprintf( fullname,
                "%s\\%s%s.avi",
                mydocs,
                buf,
                i ? istring : ""
                );

            i++;
        }
        while( _stat( fullname, &sta ) != -1 );

        SetDlgItemText( hwnd, IDC_OUTPUT_EDIT, fullname );

        SetWindowText( hwnd, "0.00%" );
        SetDlgItemText( hwnd, IDC_INPUT_TEXT, str_input );
        SetDlgItemText( hwnd, IDC_OUTPUT_TEXT, str_output );
        SetDlgItemText( hwnd, IDC_BROWSE_OUT, str_browse );
        SetDlgItemText( hwnd, IDC_START_AVI, str_start );
        SetDlgItemText( hwnd, IDC_STOP_AVI, str_stop );
        SetDlgItemText( hwnd, IDC_TIME_TAKEN_TXT, str_time_taken );
        SetDlgItemText( hwnd, IDC_VIDEO_TIME_TXT, str_video_time );
        SetDlgItemText( hwnd, IDC_PRIORITY_STATIC, str_priority );

        {
            int Ipriorities[] =        { -15,    -2,    -1,    0,    1,    2 };
            char *Cpriorities[] =    { "-15",    "-2",    "-1",    "0",    "1",    "2" };
            SendMessage( GetDlgItem(hwnd, IDC_PRIORITY), CB_RESETCONTENT, 0, 0 );
            for( i = 0 ; i < 6 ; i++ ) {
                int index;
                index = SendMessage( GetDlgItem(hwnd, IDC_PRIORITY), CB_ADDSTRING, 0, (LPARAM) Cpriorities[i] );
                SendMessage( GetDlgItem(hwnd, IDC_PRIORITY), CB_SETITEMDATA, index, (LPARAM) Ipriorities[i] );
            }
            SendDlgItemMessage( hwnd, IDC_PRIORITY, CB_SETCURSEL, 3, 0 );
        }

        SetDlgItemInt( hwnd, IDC_EDIT_FPS, 15, FALSE );

        if( thexport->thplay->Sicon )
            SendMessage(hwnd, WM_SETICON, ICON_SMALL, (LPARAM)thexport->thplay->Sicon);
        if( thexport->thplay->Licon )
            SendMessage(hwnd, WM_SETICON, ICON_BIG, (LPARAM)thexport->thplay->Licon);
    }
        break;
    case WM_TIMER:
        fix_avi_info( thexport );
        break;
    case WM_CLOSE:
    {
        int ret;

        if( thexport->avifile->exporting ) {
            SetFocus( hwnd );
            SuspendThread( thexport->handle );
            KillTimer( thexport->hwnd, thexport->ID_TIMER );
            ret = MessageBox( hwnd, str_stop_exporting, str_stop_exporting, MB_YESNO );
            SetTimer( thexport->hwnd, thexport->ID_TIMER, AVI_TIME, NULL );
            ResumeThread( thexport->handle );
            if( ret == IDNO ) {
                thexport->thplay->ret = FALSE;
                return TRUE;
            }
            thexport->avifile->exporting = 2;
            WaitForSingleObject( thexport->handle, INFINITE );
            SetDlgItemText( thexport->hwnd, IDC_STATIC_AVI, str_done_exporting );
            EnableWindow( GetDlgItem( thexport->hwnd, IDC_STOP ), FALSE );
            EnableWindow( GetDlgItem( thexport->hwnd, IDC_SAVE_AVI ), TRUE );
            KillTimer( thexport->hwnd, thexport->ID_TIMER );
        }
        thexport->thplay->ret = TRUE;

        kill_avifile( thexport->avifile );
        kill_decoder( thexport->decoder );

        if( thexport->previous )
            thexport->previous->next = thexport->next;
        if( thexport->next )
            thexport->next->previous = thexport->previous;
        if( thexport == hexports )
            hexports = thexport->next;
        free( thexport );
        DestroyWindow( hwnd );
    }
        break;
    case WM_COMMAND:
        switch(LOWORD(wParam)) {
            case IDC_BROWSE_OUT:
            {
                char *fname;
                if( (fname = SaveFileDlg( hwnd, "avi file\0*.avi\0", "avi", '\0' )) ) {
                    strcpy( thexport->avifile->fname, fname );
                    SetDlgItemText( hwnd, IDC_OUTPUT_EDIT, fname );
                }
            }
                break;
            case IDC_STOP_AVI:
            {
                if( thexport->avifile->exporting ) {
                    int lres;
                    SuspendThread( thexport->handle );
                    KillTimer( thexport->hwnd, thexport->ID_TIMER );
                    lres = MessageBox( hwnd, str_stop_exporting, str_stop_exporting, MB_YESNO );
                    SetTimer( thexport->hwnd, thexport->ID_TIMER, AVI_TIME, NULL );
                    ResumeThread( thexport->handle );
                    if( lres == IDYES ) {
                        thexport->avifile->exporting = 2;
                        WaitForSingleObject( thexport->handle, INFINITE );
                        SetDlgItemText( thexport->hwnd, IDC_STATIC_AVI, str_done_exporting );
                        EnableWindow( GetDlgItem( thexport->hwnd, IDC_STOP ), FALSE );
                        EnableWindow( GetDlgItem( thexport->hwnd, IDC_SAVE_AVI ), TRUE );
                        KillTimer( thexport->hwnd, thexport->ID_TIMER );
                    }
                }
            }
                break;
            case IDC_PRIORITY:
                if( HIWORD(wParam) == CBN_SELCHANGE) {
                    thexport->priority = SendDlgItemMessage( hwnd, IDC_PRIORITY, CB_GETITEMDATA, SendDlgItemMessage( hwnd, IDC_PRIORITY, CB_GETCURSEL, 0, 0 ), 0 );
                    SetThreadPriority( thexport->handle, thexport->priority );
                }
                break;
            case IDC_START_AVI:
            {
                int exp_ret;
                SetDlgItemText( hwnd, IDC_STATIC_AVI, "" );

                thexport->avifile->fps = GetDlgItemInt( hwnd, IDC_EDIT_FPS, FALSE, FALSE );
                if (!thexport->avifile->fps)
                    thexport->avifile->fps = 15;

                thexport->priority = SendDlgItemMessage( hwnd, IDC_PRIORITY, CB_GETITEMDATA, SendDlgItemMessage( hwnd, IDC_PRIORITY, CB_GETCURSEL, 0, 0 ), 0 );
                GetDlgItemText( hwnd, IDC_OUTPUT_EDIT, thexport->avifile->fname, MAX_PATH );

                SetCursor( LoadCursor( NULL, IDC_WAIT ) );
                ShowCursor( TRUE );

                SetDlgItemText( thexport->hwnd, IDC_STATIC_AVI, str_wait );
                if( ( exp_ret = export_video_start( thexport ) ) )
                    SetDlgItemText( thexport->hwnd, IDC_STATIC_AVI, clean_export( thexport, exp_ret ) );
                else {
                    //success
                    EnableWindow( GetDlgItem( thexport->hwnd, IDC_STOP_AVI ), TRUE );
                    EnableWindow( GetDlgItem( thexport->hwnd, IDC_START_AVI ), FALSE );
                    SetDlgItemText( thexport->hwnd, IDC_STATIC_AVI, "" );
                    thexport->handle = CreateThread( NULL, 0, (LPTHREAD_START_ROUTINE) ExportThread, (LPVOID) thexport, 0, &thexport->dwThreadId );
                    thexport->priority = SendDlgItemMessage( hwnd, IDC_PRIORITY, CB_GETITEMDATA, SendDlgItemMessage( hwnd, IDC_PRIORITY, CB_GETCURSEL, 0, 0 ), 0 );
                    SetThreadPriority( thexport->handle, thexport->priority );
                }

                ShowCursor( FALSE );
                SetCursor( LoadCursor( NULL, IDC_ARROW ) );
            }
                break;
        }
    break;
    default:
        return FALSE;
    }
    return TRUE;
}

char *clean_export( hexport_t *hexport, int exp_ret )
{
    char *errbuf = 0;

    switch( exp_ret ) {
    case CLEAN_ALL:

    case AVISTREAMSETFORMAT:
        if( !errbuf ) errbuf = str_error_stream_format;
        AVIStreamClose( hexport->avifile->psCompressed );

    case AVIMAKECOMPRESSEDSTREAM:
        if( !errbuf ) errbuf = str_error_compressed_stream;

    case AVISAVEOPTIONS:
        if( !errbuf ) errbuf = str_error_compressor;
        AVIStreamClose( hexport->avifile->ps );

    case AVIFILECREATESTREAM:
        if( !errbuf ) errbuf = str_error_stream;
        AVIFileClose( hexport->avifile->pfile );

    case AVIFILEOPEN:
        if( !errbuf ) errbuf = str_error_output;
        AVIFileExit( );
    }
    return errbuf;
}

static void fix_avi_info( hexport_t *hexport )
{
    char buf[16];
    HWND hwnd = hexport->hwnd;
    avifile_t *avifile = hexport->avifile;
    decoder_t *decoder = hexport->decoder;
    int imp_i = hexport->avifile->imp_i;
    int exp_i = hexport->avifile->exp_i;
    DWORD firsttick = hexport->avifile->firsttick;
    DWORD curtick = GetTickCount( );
    int tickdif = curtick - firsttick;
    int curtime = exp_i * 1000 / avifile->fps;
    float percent = (float) curtime / (decoder->out->real_time - decoder->in->real_time) * 100;

    SetDlgItemInt( hwnd, IDC_FRAMES_IN, imp_i, FALSE );
    SetDlgItemInt( hwnd, IDC_FRAMES_OUT, exp_i, FALSE );
    sprintf( buf, "%.2f", (float) imp_i / tickdif * 1000 );
    SetDlgItemText( hwnd, IDC_FPS_IN, buf );
    sprintf( buf, "%.2f", (float) exp_i / tickdif * 1000 );
    SetDlgItemText( hwnd, IDC_FPS_OUT, buf );
    sprintf( buf, "%.2d:%.2d:%.2d:%.2d", (tickdif / 10 / 360000) % 100, (tickdif / 10 / 6000) % 60, (tickdif / 10 / 100) % 60, tickdif / 10 % 100 );
    SetDlgItemText( hwnd, IDC_TIME_TAKEN, buf );
    sprintf( buf, "%.2d:%.2d:%.2d:%.2d", (curtime / 10 / 360000) % 100, (curtime / 10 / 6000) % 60, (curtime / 10 / 100) % 60, curtime / 10 % 100 );
    SetDlgItemText( hwnd, IDC_VIDEO_TIME, buf );
    if( percent > 100 )
        percent = 100;
    sprintf( buf, "%.2f%%", percent );
    SetDlgItemText( hwnd, IDC_PERCENT_TXT, buf );
    SetWindowText( hwnd, buf );
    SendDlgItemMessage( hwnd, IDC_PROGRESS, PBM_SETPOS, curtime, 0 );
}
